package predicate

type JoinOp string

func (j JoinOp) String() string {
	return string(j)
}

var (
	leftJoinOp  JoinOp = "Left Join"
	rightJoinOp JoinOp = "Right Join"
	joinOp      JoinOp = "Join"
	// ... cross join
)

type Join struct {
	Alias string
	Left  TableReference
	Right TableReference
	Op    JoinOp
	On    []Predicate
	Using []Column
}

func (j Join) alias() {}
func (j Join) tableReference() {
}

func (j Join) As(alias string) Join {
	return Join{
		Left:  j.Left,
		Right: j.Right,
		Op:    j.Op,
		Alias: alias,
	}
}

// 使用JoinBuilder原因： join语句到这还没构建完成，还需要有on||using才完整

func (j Join) Join(other TableReference) JoinBuilder {
	return JoinBuilder{
		left:  j,
		right: other,
		op:    joinOp,
	}
}

func (j Join) LeftJoin(other TableReference) JoinBuilder {
	return JoinBuilder{
		left:  j,
		right: other,
		op:    leftJoinOp,
	}
}

func (j Join) RightJoin(other TableReference) JoinBuilder {
	return JoinBuilder{
		left:  j,
		right: other,
		op:    rightJoinOp,
	}
}

var _ TableReference = Join{}
var _ Alias = Join{}

type JoinBuilder struct {
	left  TableReference
	right TableReference
	op    JoinOp
}

func (j JoinBuilder) On(predicates ...Predicate) Join {
	return Join{
		Left:  j.left,
		Right: j.right,
		Op:    j.op,
		On:    predicates,
	}
}

func (j JoinBuilder) Using(columns ...Column) Join {
	return Join{
		Left:  j.left,
		Right: j.right,
		Op:    j.op,
		Using: columns,
	}
}
